package inno.data;
import java.util.ArrayList;
import java.util.HashMap;


// mvAvg in format of startingDay, bump and the value
public class MovingAvg {
	
	private ArrayList<Double> stocksPrice;
	private HashMap<Integer,HashMap<Integer,Double>> stocksMvAvg;
	private int[] bumps;
	private int bumpsNum;
	
	public MovingAvg(ArrayList<Double> price, int[] bumps, int bumpsNum ){
		stocksPrice = price;
		stocksMvAvg = new HashMap<Integer, HashMap<Integer,Double>>();
		this.bumps = bumps;
		this.bumpsNum = bumpsNum;
		initialize();
	}
	
	// initialize the map for a desired bump
	private void initialize(){		
		//int bumpsNum = 10;
		// this are the bumps that we are going to use 
		//int[] bumps = {5,10,15,25,50,75,100,125,150,175};
		for (int i=0; i<stocksPrice.size();i++){
			stocksMvAvg.put(i, new HashMap<Integer,Double>());
		}
		for (int i=0; i<bumpsNum;i++){
			initializeBump(bumps[i]);
		}
	}
	
	private void initializeBump(int desiredBump){
		int bump = desiredBump;
		double sum = 0;
		
		// do the first sumerize
		int firstIndex = stocksPrice.size()-1;
		for (int j=0;j<bump;j++){
			sum+=stocksPrice.get(firstIndex-j);
		}
		double avg = sum / bump;
		HashMap<Integer,Double> newAvg = stocksMvAvg.get(firstIndex);
		newAvg.put(bump, new Double(avg));
		stocksMvAvg.put(new Integer(firstIndex), newAvg);
		
		// and then use it for the rest of the numbers
		int lastIndex = stocksPrice.size()-bump;
		for (int i=1;i<lastIndex; i++){
			int newIndex = stocksPrice.size()-i-1;
			sum = sum - stocksPrice.get(newIndex+1) + stocksPrice.get(newIndex+1-bump);
			avg = sum / bump;
			newAvg = stocksMvAvg.get(newIndex);
			newAvg.put(bump, new Double(avg));
			stocksMvAvg.put(new Integer(newIndex), newAvg);
		}
	}
	
	// returns the mvAvg from a day in a givven bump
	public double getMvAvg(int day,int bump){
		HashMap<Integer,Double> newAvg = stocksMvAvg.get(day);
		if (day<5){
			newAvg = stocksMvAvg.get(6);
		}
		if (null==newAvg){
			// if the values doesn't exist try day 0
			newAvg = stocksMvAvg.get(200);	
		}
		
		if (null!=newAvg.get(bump)){
			return newAvg.get(bump);
		}
		
		// means that this bump doesn't exist, try lower bump
		else{
			int i;
			for (i=bumpsNum-1;i>=0;i--){
				if (bumps[i]<bump){
					if (null!=newAvg.get(bumps[i])){
						return newAvg.get(bumps[i]);
					}
				}
			}

			// else (like negative number, return for the lowest bump)
			if ( newAvg.get(bumps[0])==null){
				return bump;
			}
			return newAvg.get(bumps[0]);
		}
	}

}
